import { MathUtils } from "../../api/math/MathUtils";
import { E_GameBaseAttr } from "../defs/com/E_GameBaseAttr";
import { E_Quality } from "../defs/com/E_Quality";
import { E_EquipAttrType } from "../defs/equip/E_EquipAttrType";
import { E_EquipGlobal } from "../defs/equip/E_EquipGlobal";
import { E_ItemType } from "../defs/item/E_ItemType";
import { E_PrayEffectType } from "../defs/lord/E_PrayEffectType";
import { E_MailFromType } from "../defs/mail/E_MailFromType";
import { E_MailId } from "../defs/mail/E_MailId";
import { E_MailRewardStatus } from "../defs/mail/E_MailRewardStatus";
import { E_PlayerIncID } from "../defs/player/E_PlayerIncID";
import { E_MsgCode } from "../defs/proto/E_MsgCode";
import { CDEquipment } from "../excel/CDEquipment";
import { CDEquipmentChange } from "../excel/CDEquipmentChange";
import { CDEquipmentGlobal } from "../excel/CDEquipmentGlobal";
import { CDEquipmentLevel } from "../excel/CDEquipmentLevel";
import { CDEquipmentRMath } from "../excel/CDEquipmentRMath";
import { CDEquipmentStrengthen } from "../excel/CDEquipmentStrengthen";
import { CDEquipmentUpgrade, E_CDEquipmentUpgrade } from "../excel/CDEquipmentUpgrade";
import { CDItem } from "../excel/CDItem";
import { CDMath, E_CDMath } from "../excel/CDMath";
import { CEEquipmentLevel } from "../excel_extend/CEEquipmentLevel";
import { CEMath } from "../excel_extend/CEMath";
import { Equip } from "../struct/Equip";
import { EquipManager } from "../struct/EquipManager";
import { Player } from "../struct/Player";
import { SDBattle } from "./SDBattle";
import { SDHandBook } from "./SDHandBook";
import { SDHuangXiaoxi } from "./SDHuangXiaoxi";
import { SDPlayer } from "./SDPlayer";
import { SDPray } from "./SDPray";


/**
 * 数据-装备
 */
export abstract class SDEquip {


    /**
     * 从各种可能的渠道获取装备
     * @param player 
     * @param equipId 
     * @returns 
     */
    public static getEquipById(player: Player, equipId: number): Equip {
        let equip = player.equipManager.getEquip(equipId);
        if (!equip) {
            equip = this.getEquipInBagFullMail(player, equipId);
        }
        return equip;
    }


    /**
     * 获取背包放不下的装备
     * @param player 
     * @param equipId 
     */
    public static getEquipInBagFullMail(player: Player, equipId: number): Equip {
        const list = player.mailBox.getMailValues();
        for (let i = list.length - 1; i >= 0; i--) {
            const mail = list[i];
            if (mail.mailFromType !== E_MailFromType.Excel
                || mail.configId !== E_MailId.BagFull
                || mail.rewardStatus !== E_MailRewardStatus.Doing) {
                continue;
            }
            const equip = mail.drop.getEquip(equipId);
            if (equip) {
                return equip;
            }
        }
        return null;
    }

    /**
     * 获取最高装备等级
     * @param player 
     * @returns 
     */
    public static getEquipLevelMax(player: Player, wearOn = false): number {
        let lv = 0;

        if (wearOn) {
            const vs = player.equipManager.getWearValues();
            for (let i = 0, len = vs.length; i < len; i++) {
                const equip = player.equipManager.getEquip(vs[i]);
                if (equip && equip.level > lv) {
                    lv = equip.level;
                }
            }
        }
        else {
            const vs = player.equipManager.getEquipValues();
            for (let i = 0, len = vs.length; i < len; i++) {
                if (vs[i].level > lv) {
                    lv = vs[i].level;
                }
            }
        }

        return lv;
    }


    /**
     * 装备是否可以转化
     * @param player 
     * @param id 
     * @param checkItem 
     * @returns 0-可以，其他-不行
     */
    public static isCanChange(player: Player, id: number, checkItem: boolean): number {
        const equip = player.equipManager.getEquip(id);
        if (!equip) {
            return E_MsgCode.EquipNotFind;
        }

        const needQuality = CDEquipmentGlobal.getData(E_EquipGlobal.TransQuality).value;
        if (equip.quality < needQuality) {
            return 1;   //品质不符合要求
        }

        const needLevel = CDEquipmentGlobal.getData(E_EquipGlobal.TransLevel).value;
        if (equip.level < needLevel) {
            return 2;   //等级不符合要求
        }

        const changeConfig = CDEquipmentChange.getData(equip.level);
        if (!changeConfig) {
            return E_MsgCode.EquipChangeConfigNotFind;
        }

        if (checkItem) {
            const costItemID = changeConfig.costItem;
            const costItemNum = changeConfig.costNum;
            const count = player.getItemNum(costItemID);
            if (count < costItemNum) {
                return E_MsgCode.ItemNotEnough;   //道具不足
            }
        }

        return 0;
    }


    /**
     * 装备是否可以升级
     * @param player 
     * @param id 
     * @param firstEquipID 
     * @returns 0-可以，其他-不行
     */
    public static isCanLevelUp(player: Player, id: number, firstEquipID: number): number {
        const equip = player.equipManager.getEquip(id);
        if (!equip) {
            return E_MsgCode.EquipNotFind;
        }

        const needQuality = CDEquipmentGlobal.getData(E_EquipGlobal.LevelupQuality).value;
        if (equip.quality < needQuality) {
            return 1;   //品质不符合要求
        }

        const needLevel = CDEquipmentGlobal.getData(E_EquipGlobal.LevelupLevel).value;
        if (equip.level < needLevel) {
            return 2;   //等级不符合要求
        }

        const wearList = player.equipManager.getWearValues();
        if (wearList.indexOf(id) >= 0) {
            return 6;   //穿戴中
        }

        if (firstEquipID > 0) {
            const firstEquip = player.equipManager.getEquip(firstEquipID);
            if (equip.quality !== firstEquip.quality) {
                return 3;   //品质不一致
            }
            if (equip.level !== firstEquip.level) {
                return 4;   //等级不一致
            }
        }

        //升级配置
        const upgradeConfig = CDEquipmentUpgrade.getData(equip.level);
        if (!upgradeConfig) {
            return E_MsgCode.EquipUpgradeConfigNotFind;
        }

        //升级概率
        //  const rate = upgradeConfig.getAttr(E_CDEquipmentUpgrade.successRate_2 + (ids.length - 2));
        //  if (!rate) {
        //      return ExceptionUtils.addMsgErrorInfo({
        //          c: 5,
        //          i: ids.length
        //      });
        //  }

        return 0;
    }


    /**
     * 装备是否可以升级
     * @param player 
     * @param ids 
     * @param outInfo 
     * @returns 0-可以，其他-不行
     */
    public static isCanLevelUpList(player: Player, ids: number[], outInfo: number[], skipLength: boolean): number {
        //至少两个装备
        if (!ids || (!skipLength && ids.length < 2)) {
            return 7;
        }

        const needQuality = CDEquipmentGlobal.getData(E_EquipGlobal.LevelupQuality).value;
        const needLevel = CDEquipmentGlobal.getData(E_EquipGlobal.LevelupLevel).value;
        const wearList = player.equipManager.getWearValues();
        let selQuality = 0;
        let selLevel = 0;

        for (let i = 0; i < ids.length; i++) {
            if (outInfo) {
                outInfo[0] = ids[i];
            }

            const equip = player.equipManager.getEquip(ids[i]);
            if (!equip) {
                return E_MsgCode.EquipNotFind;
            }

            if (equip.quality < needQuality) {
                return 1;   //品质不符合要求
            }

            if (equip.level < needLevel) {
                return 2;   //等级不符合要求
            }

            if (i === 0) {
                selQuality = equip.quality;
                selLevel = equip.level;
            }
            else if (selQuality !== equip.quality) {
                return 3;  //品质不一致
            }
            else if (selLevel !== equip.level) {
                return 4;  //等级不一致
            }

            if (wearList.indexOf(ids[i]) >= 0) {
                return 6;  //穿戴中
            }
        }
        if (outInfo) {
            outInfo[0] = -1;
        }

        //升级配置
        const upgradeConfig = CDEquipmentUpgrade.getData(selLevel);
        if (!upgradeConfig) {
            return E_MsgCode.EquipUpgradeConfigNotFind;
        }

        //升级概率
        if (!skipLength) {
            const rate: number = upgradeConfig.getAttr(E_CDEquipmentUpgrade.successRate_2 + (ids.length - 2));
            if (rate === -1) {
                return 5;    //升级概率
            }
        }

        //消耗
        const costItemID = upgradeConfig.costItem;
        const costItemNum = upgradeConfig.costNum;
        const count = player.getItemNum(costItemID);

        if (outInfo) {
            outInfo[0] = costItemID;
            outInfo[1] = costItemNum;
        }

        if (count < costItemNum) {
            return E_MsgCode.ItemNotEnough;
        }

        if (outInfo) {
            outInfo[2] = selQuality;
            outInfo[3] = selLevel;
        }

        //可以
        return 0;
    }


    /**
     * 指定等级装备的已穿戴数量
     * @param player 
     * @param quality 
     */
    public static getQualityEquipWearNum(player: Player, quality: E_Quality): number {
        const equipManager: EquipManager = player.equipManager;
        const wearIds = equipManager.getWearValues();

        let count = 0;

        for (let i = 0, len = wearIds.length; i < len; i++) {
            const eq = equipManager.getEquip(wearIds[i]);
            if (!eq) {
                //  console.warn('穿了一件找不到的装备, ID = ' + wearIds[i]);
                continue;
            }
            if (eq.quality >= quality) {
                count++;
            }
        }

        return count;
    }

    /**
     * 指定等级装备的可穿戴数量
     * @param player 
     * @param quality 
     * @returns <0-无限制
     */
    public static getQualityEquipWearMaxNum(player: Player, quality: E_Quality): number {
        if (quality === E_Quality.Red) {
            let v = 0;
            const mythNum = CDEquipmentGlobal.getData(E_EquipGlobal.MythBaseWearNum).value;
            v += mythNum;

            //祝福加成
            {
                const n = SDPray.getEffectByType(player, E_PrayEffectType.RedEquipNum);
                v += n;
            }
            //黄小西加成
            {
                const n = SDHuangXiaoxi.getEffectByType(player, E_PrayEffectType.RedEquipNum);
                v += n;
            }
            //TODO 其他加成

            return v;
        }

        return -1;
    }


    /**
     * 获取指定全属性值
     * @param equip 
     * @param idx 
     * @returns 
     */
    public static getAttrAll(equip: Equip, idx: E_GameBaseAttr): number {
        let v = 0;
        for (let i = 0; i < E_EquipAttrType.EnumCount; i++) {
            v += this.getAttr(equip, i, idx);
        }
        return v;
    }


    /**
     * 获取等级加成
     * @param equip 
     * @returns 
     */
    public static getLevelAddCoef(equip: Equip): number {
        let levelAddCoef = 0;
        const levelConfig = this.getLevelConfig(equip);
        if (levelConfig) {
            levelAddCoef = levelConfig.addCoef;
        }
        return levelAddCoef;
    }


    /**
     * 获取强化加成
     * @param equipOrStreng 
     * @returns 
     */
    public static getStrengthenAddCoef(equipOrStreng: Equip | number): number {
        const strengthLv = (equipOrStreng instanceof Equip) ? this.getStrengthConfigID(equipOrStreng) : equipOrStreng;
        if (0 < strengthLv) {
            const strengthConfig = CDEquipmentStrengthen.getData(strengthLv);
            if (strengthConfig) {
                return strengthConfig.strengthenAdd;
            }
            else {
                console.warn('CDEquipmentStrengthen 获取不到 ID = ' + strengthLv);
            }
        }
        return 0;
    }


    /**
     * 通过值获取最终属性
     * @param basev 
     * @param levelAddCoef 
     * @param strengthAddCoef 
     * @returns 
     */
    public static getAttrByValue(
        basev: number,
        levelAddCoef: number,
        strengthAddCoef: number
    ): number {
        let v = basev * (levelAddCoef / 100);
        v = v * (1 + strengthAddCoef / 100);
        v = Math.floor(v);
        return v;
    }


    /**
     * 获取指定类型的映射表
     * @param equip 
     * @param type 
     */
    public static getTypeMapValue(equip: Equip, type: E_EquipAttrType, k: number): number {
        if (!equip) {
            return 0;
        }
        switch (type) {
            case E_EquipAttrType.Main: return equip.getMainAttribute(k);
            case E_EquipAttrType.Base: return equip.getBaseAttribute(k);
            case E_EquipAttrType.Random: return equip.getRandomAttribute(k);
            default: return 0;
        }
    }


    /**
     * 获取类型属性值
     * @param type 
     * @param idx 
     */
    public static getAttr(equip: Equip, type: E_EquipAttrType, idx: E_GameBaseAttr): number {
        const v = this.getTypeMapValue(equip, type, idx);
        if (!v) {
            return 0;
        }

        const levelAddCoef = this.getLevelAddCoef(equip);
        let strengthAddCoef = 0;
        if (type !== E_EquipAttrType.Base) {
            strengthAddCoef = this.getStrengthenAddCoef(equip);
        }
        return this.getAttrByValue(v, levelAddCoef, strengthAddCoef);
    }


    /**
     *  统计数据
     * @param equip 
     * @param outList 
     * @returns 
     */
    public static addGameBaseAttr(equip: Equip, outList: number[]): void {
        if (!equip || !outList) {
            return;
        }

        //等级和强化
        const levelAddCoef = this.getLevelAddCoef(equip);

        //基础值
        {
            const strengthAddCoef = this.getStrengthenAddCoef(equip);
            //主
            {
                const ks = equip.getMainAttributeKeys();
                const vs = equip.getMainAttributeValues();
                for (let i = vs.length - 1; i >= 0; i--) {
                    outList[ks[i]] += this.getAttrByValue(vs[i], levelAddCoef, strengthAddCoef);
                }
            }
            //随机
            {
                const ks = equip.getRandomAttributeKeys();
                const vs = equip.getRandomAttributeValues();
                for (let i = vs.length - 1; i >= 0; i--) {
                    outList[ks[i]] += this.getAttrByValue(vs[i], levelAddCoef, strengthAddCoef);
                }
            }
        }

        //固定
        {
            const ks = equip.getBaseAttributeKeys();
            const vs = equip.getBaseAttributeValues();
            for (let i = vs.length - 1; i >= 0; i--) {
                for (let i = E_GameBaseAttr.EnumCount - 1; i >= 0; i--) {
                    outList[ks[i]] += this.getAttrByValue(vs[i], levelAddCoef, 0);
                }
            }
        }

        //技能加成，统一到技能那边了
    }


    /**
     * 是否能萃取
     * @param player 
     * @param equipID 
     */
    public static isCanExtract(player: Player, equipID: number): boolean {
        const equip = player.equipManager.getEquip(equipID);
        if (!equip) {
            return false;
        }
        const config = SDEquip.getEquipConfig(equip);
        if (config.runeID === 0) {
            return false;
        }
        if (player.getItemNum(config.runeID) > 0) {
            return false;
        }

        const itemConfig = SDEquip.getItemConfig(equip);
        if (itemConfig.color < CDEquipmentGlobal.getData(E_EquipGlobal.ExtractQuality).value) {
            return false;
        }

        if (equip.level < CDEquipmentGlobal.getData(E_EquipGlobal.ExtractMaxLevel).value) {
            return false;
        }

        return true;
    }


    /**
     * 获取装备配置
     * @param data 
     * @param equipID 
     * @returns 
     */
    public static getEquipConfig(equip: Equip): CDEquipment {
        if (!equip) {
            return null;
        }
        const config = CDEquipment.getData(equip.configId);
        if (!config) {
            console.warn('CDEquipment 获取不到 ID = ' + equip.configId);
        }
        return config;
    }


    /**
     * 获取道具配置
     * @param equip 
     * @returns 
     */
    public static getItemConfig(equip: Equip): CDItem {
        if (!equip || 0 === equip.configId) {
            return null;
        }
        const config = CDItem.getData(equip.configId);
        return config;
    }


    /**
    * 获取强化配置
    * @param data 
    * @param equipID 
    * @returns 
    */
    public static getStrengthConfig(equip: Equip): CDEquipmentStrengthen {
        const id = this.getStrengthConfigID(equip);
        const config = CDEquipmentStrengthen.getData(id);
        if (!config) {
            console.warn('CDEquipmentStrengthen 获取不到 ID = ' + id);
        }
        return config;
    }


    /**
    * 获取强化配置id
    * @param equip 
    * @returns 
    */
    public static getStrengthConfigID(equip: Equip): number {
        return equip.streng;
    }


    /**
     * 获取等级配置
     * @param equip  
     * @returns 
     */
    public static getLevelConfig(equip: Equip): CDEquipmentLevel {
        const id = this.getLevelConfigId(equip);
        const config = CDEquipmentLevel.getData(id);
        if (!config) {
            console.warn('CDEquipmentLevel 获取不到 ID = ' + id);
        }
        return config;
    }


    /**
     * 获取等级配置id
     * @param equip 
     * @returns 
     */
    public static getLevelConfigId(equip: Equip): number {
        return equip.level * 10 + equip.quality;
    }


    /**
     * 获取指定属性的随机范围
     * @param rm 
     * @param k 
     */
    public static getRMathRandomList(config: CDEquipmentRMath, idx: E_GameBaseAttr): number[] {
        let nums: number[] = null;

        switch (idx) {
            case E_GameBaseAttr.phyAtk:
                nums = config.phyAtk;
                break;

            case E_GameBaseAttr.fireAtk:
                nums = config.fireAtk;
                break;

            case E_GameBaseAttr.iceAtk:
                nums = config.iceAtk;
                break;

            case E_GameBaseAttr.lightAtk:
                nums = config.lightAtk;
                break;

            case E_GameBaseAttr.hp:
                nums = config.hp;
                break;

            case E_GameBaseAttr.hpRegen:
                nums = config.hpRegen;
                break;

            case E_GameBaseAttr.manaRegen:
                nums = config.manaRegen;
                break;

            case E_GameBaseAttr.dribbleRegen:
                nums = config.dribbleRegen;
                break;

            case E_GameBaseAttr.dodgeRegen:
                nums = config.dodgeRegen;
                break;

            case E_GameBaseAttr.critRegen:
                nums = config.critRegen;
                break;

            case E_GameBaseAttr.blockRegen:
                nums = config.blockRegen;
                break;

            default:
                console.error('CDEquipmentRMath can not find attrs, idx = ' + idx);
                break;
        }

        return nums;
    }


    /**
     * 获取随机值
     * @param idx 
     * @param config 
     * @param possible 
     * @returns 
     */
    public static getRMathRandomV(idx: number, config: CDEquipmentRMath, possible = false): number {
        const nums = this.getRMathRandomList(config, idx);
        if (nums && nums.length === 2) {
            if (possible) {
                return nums[0];
            }
            else {
                const rv = MathUtils.random(nums[0], nums[1]);
                return rv;
            }
        }
        else {
            console.error('CDEquipmentRMath attrs length !== 2 ID = ' + config.id);
            return 0;
        }
    }


    /**
    * 初始化固定属性
    * @param equip 
    * @param config 
    * @param levelConfig 
    */
    public static initBaseAttr(equip: Equip, config: CDEquipment, levelConfig: CDEquipmentLevel): void {
        equip.clearBaseAttributeMap();
        if (config.baseMath === 0 || levelConfig.baseMathCoef === 0) {
            return;
        }

        do {
            const mconfig = CDMath.getData(config.baseMath);
            if (!mconfig) {
                console.error('CDMath baseMath can not find ID = ' + config.baseMath);
                break;
            }

            // const ratio = levelConfig.baseMathCoef / 100;    //不计算，后面求职时统一计算了 this.getAttrByValue

            for (let i = E_CDMath.id + 1, len = E_CDMath.EnumCount; i < len; i++) {
                const v: number = mconfig.getAttr(i);
                if (v === 0) {
                    continue;
                }
                const idx = CEMath.getGameAttrTypeByExcelType(i);
                equip.putBaseAttribute(idx, v);
            }
        } while (false);
    }


    /**
    * 创建新装备
    * @param player 
    * @param equipManager 
    * @param configId 
    * @param level 
    * @returns 
    */
    public static createNew(player: Player, configId: number, level: number): Equip {
        //装备配置
        const config = CDEquipment.getData(configId);
        if (!config) {
            console.error('CDEquipment 获取不到 ID = ' + configId);
            return null;
        }

        //等级配置
        const levelConfigId = level * 10 + config.color; //与 this.getLevelConfigId()  保持一致
        const levelConfig = CDEquipmentLevel.getData(levelConfigId);
        if (!levelConfig) {
            console.error('CDEquipmentLevel 获取不到 ID = ' + levelConfigId);
            return null;
        }

        //道具配置
        const itemConfig = CDItem.getData(configId);
        if (!itemConfig) {
            console.error('CDItem 获取不到 ID = ' + configId);
            return null;
        }

        //产生新装备
        const equip = Equip.create();
        equip.equipId = player ? SDPlayer.getUniqueIndex(player, E_PlayerIncID.Equip) : -1;
        equip.configId = configId;
        equip.quality = config.color;
        equip.level = level;

        //产生属性
        SDEquip.initBaseAttr(equip, config, levelConfig);
        SDEquip.reforge(equip, config, levelConfig);

        //添加进角色数据
        if (player) {
            player.equipManager.putEquip(equip.equipId, equip);
            SDHandBook.checkId(player, E_ItemType.Equip, configId);
        }

        return equip;
    }


    /**
     * 洗练
     * @param equip 
     * @param config 
     * @param levelConfig 
     */
    public static recast(equip: Equip, config: CDEquipment, levelConfig: CDEquipmentLevel): void {
        //主属性
        do {
            const rconfig = CDEquipmentRMath.getData(config.primeRMath);
            if (!rconfig) {
                console.error('CDEquipmentRMath can not find ID = ' + config.primeRMath);
                break;
            }
            if (config.primeAttribute.length === 0) {
                console.error('CDEquipment primeAttribute length === 0 ID = ' + config.id);
                break;
            }

            const ks = equip.getMainAttributeKeys();
            for (let i = 0, len = ks.length; i < len; i++) {
                const attrIdx = ks[i];
                const v = this.getRMathRandomV(attrIdx, rconfig, equip.equipId <= 0);
                equip.putMainAttribute(attrIdx, v);
            }
        } while (false);

        //随机属性
        do {
            const rconfig = CDEquipmentRMath.getData(config.randomRMath);
            if (!rconfig) {
                console.error('CDEquipmentRMath can not find ID = ' + config.randomRMath);
                break;
            }
            if (config.randomNum.length === 0) {
                console.error('CDEquipment randomNum length === 0 ID = ' + config.id);
                break;
            }

            const ks = equip.getRandomAttributeKeys();
            for (let i = 0, len = ks.length; i < len; i++) {
                const attrIdx = ks[i];
                const v = this.getRMathRandomV(attrIdx, rconfig, equip.equipId <= 0);
                equip.putRandomAttribute(attrIdx, v);
            }
        } while (false);
    }


    /**
     * 重铸
     * @param equip 
     * @param config 
     * @param levelConfig 
     */
    public static reforge(equip: Equip, config: CDEquipment, levelConfig: CDEquipmentLevel): void {
        //主属性
        equip.clearMainAttributeMap();
        do {
            const rconfig = CDEquipmentRMath.getData(config.primeRMath);
            if (!rconfig) {
                console.error('CDEquipmentRMath can not find ID = ' + config.primeRMath);
                break;
            }
            if (config.primeAttribute.length === 0) {
                console.error('CDEquipment primeAttribute length === 0 ID = ' + config.id);
                break;
            }

            let idx = 0;
            if (config.primeAttribute.length > 1 && equip.equipId > 0) {
                idx = MathUtils.random(0, config.primeAttribute.length - 1);
            }
            const attrIdx = config.primeAttribute[idx];
            const v = this.getRMathRandomV(attrIdx, rconfig, equip.equipId <= 0);
            if (v !== 0) {
                equip.putMainAttribute(attrIdx, v);
            }
        } while (false);

        //随机属性
        equip.clearRandomAttributeMap();
        do {
            const rconfig = CDEquipmentRMath.getData(config.randomRMath);
            if (!rconfig) {
                console.error('CDEquipmentRMath can not find ID = ' + config.randomRMath);
                break;
            }
            if (config.randomNum.length === 0) {
                console.error('CDEquipment randomNum length === 0 ID = ' + config.id);
                break;
            }

            if (equip.equipId > 0) {
                const countIdx = MathUtils.random(0, config.randomNum.length - 1);
                const count = config.randomNum[countIdx];
                if (count <= 0) {
                    console.error('CDEquipment randomNum[' + countIdx + '] === 0 ID = ' + config.id);
                    break;
                }

                const list = MathUtils.getRandomList(config.randomAttribute, count);
                for (let i = list.length - 1; i >= 0; i--) {
                    const v = this.getRMathRandomV(list[i], rconfig, equip.equipId <= 0);
                    if (v !== 0) {
                        equip.putRandomAttribute(list[i], v);
                    }
                }
            }
            else {
                const list = config.randomAttribute;
                for (let i = 0, len = list.length; i < len; i++) {
                    const v = this.getRMathRandomV(list[i], rconfig, equip.equipId <= 0);
                    if (v !== 0) {
                        equip.putRandomAttribute(config.randomAttribute[i], v);
                    }
                }
            }
        } while (false);
    }


    /**
     * 获取强化消耗
     * @param strengthConfig 
     * @param levelConfig 
     * @returns 
     */
    public static getEquipStrengthCostNum(strengthConfig: CDEquipmentStrengthen, levelConfig: CDEquipmentLevel): number {
        return Math.floor(strengthConfig.costNum * levelConfig.strengthenCostCoef / 100);
    }


    /**
     * 分解所得
     * @param strengthConfig 
     * @param levelConfig 
     * @returns 
     */
    public static getEquipSmeltReturnNum(strengthConfig: CDEquipmentStrengthen, levelConfig: CDEquipmentLevel): number {
        let itemsNum = 0;
        if (levelConfig && levelConfig.smeltNum > 0) {
            itemsNum += levelConfig.smeltNum;
        }
        if (strengthConfig && strengthConfig.smeltNum !== 0 && levelConfig.strengthenCostCoef !== 0) {
            const addv = Math.floor(strengthConfig.smeltNum * levelConfig.strengthenCostCoef / 100);
            itemsNum += addv;
        }
        return itemsNum;
    }


    /**
     * 获取装备强度
     * @param equip 
     * @returns 
     */
    public static getFightScore(equip: Equip): number {
        if (!equip) {
            return 0;
        }

        const attrList: number[] = [];
        for (let i = E_GameBaseAttr.EnumCount - 1; i >= 0; i--) {
            attrList[i] = 0;
        }

        const levelAddCoef = this.getLevelAddCoef(equip);
        const strengthAddCoef = this.getStrengthenAddCoef(equip);
        const addScoreByAttr = (ks: number[], vs: number[], strengthAddCoef: number) => {
            for (let i = ks.length - 1; i >= 0; i--) {
                attrList[ks[i]] += this.getAttrByValue(vs[i], levelAddCoef, strengthAddCoef);
            }
        };

        addScoreByAttr(equip.getMainAttributeKeys(), equip.getMainAttributeValues(), strengthAddCoef);
        addScoreByAttr(equip.getRandomAttributeKeys(), equip.getRandomAttributeValues(), strengthAddCoef);
        addScoreByAttr(equip.getBaseAttributeKeys(), equip.getBaseAttributeValues(), 0);

        const strengthScore = SDBattle.getFightScore(attrList);

        return Math.floor(strengthScore);
    }

    /**
     * 部位是否可以强化
     * @param player
     * @param partId
     * @returns 错误码
     */
    public static isPartCanLevelUp(player: Player, partId: number): number {
        const equipManager = player.equipManager;
        const currentLevel = equipManager.getPartLevel(partId) || 0;

        // 强化等级超过了动态配置最大等级
        const maxPartLevel = CEEquipmentLevel.getPlayerPartMaxLevel(player.playerInfo.level);
        if (currentLevel >= maxPartLevel) {
            return E_MsgCode.EquipStrengthenLevelMax;
        }

        const equipid = equipManager.getWear(partId);
        if (!equipid) {
            return E_MsgCode.EquipStrengthenNotWear;
        }

        //升级配置
        const upgradeConfig = CDEquipmentStrengthen.getData(currentLevel);
        if (!upgradeConfig) {
            return E_MsgCode.EquipUpgradeConfigNotFind;
        }
        const nextLevel = currentLevel + 1;
        const nextUpgradeConfig = CDEquipmentStrengthen.getData(nextLevel);
        if (!nextUpgradeConfig) {
            return E_MsgCode.EquipStrengthenLevelMax;
        }

        //消耗
        const costItemId = upgradeConfig.costItem;
        const costItemNum = upgradeConfig.costNum;
        const count = player.getItemNum(costItemId);

        if (count < costItemNum) {
            return E_MsgCode.ItemNotEnough;
        }
        return 0;
    }



}
